/*
 *  Private classes for the compatibility routines between the old DO
 *  mechanisms and the new Foundation objects.
 *
 *  No guarantee is made for the fitness of this code for any particular
 *  use.  No warranty expressed or implied.  Use at your own risk!
 *
 *  Randy Tidd
 *  NeXT Premium Developer Support
 */
#import "FoundationExtensionsPrivate.h"
#import <remote/transport.h>
#import <foundation/NSUtilities.h>
#import <foundation/NSException.h>

@implementation _NSArrayPlaceHolder

- initWithArray:(NSArray *)anArray
{
    [super init];

    array = [anArray copy];

    return self;
}

- free
{
    [array release];

    return [super free];
}

- encodeUsing:(id <NXEncoding>)portal
{
    unsigned count, i;

    /*
     *  First encode the count
     */
    count = [array count];
    [portal encodeData:&count ofType:"i"];

    /*
     *  Then encode the objects one by one
     */
    for(i=0; i<[array count]; i++) {
	[portal encodeObject:[array objectAtIndex:i]];
    }

    return self;
}

- decodeUsing:(id <NXDecoding>)portal
{
    NSMutableArray *newArray = nil;
    unsigned count, i;

    /*
     *  We encoded the count first, and here it is
     */
    [portal decodeData:&count ofType:"i"];

    newArray = [NSMutableArray arrayWithCapacity:count];

    /*
     *  Decode the objects one by one and add them to the array
     */
   for(i=0; i<count; i++) {
	[newArray addObject:[portal decodeObject]];
    }

    /*
     *  We return our mutable array instance here even though we might
     *  be the placeholder for a regular NSArray.  There is usually no
     *  harm in returning a mutable array in place of an immutable array.
     *  If there is, you need to implement some smarts here to return an
     *  instance of the appropriate class.
     */
    return newArray;
}

@end

@implementation _NSDictionaryPlaceHolder

- initWithDictionary:(NSDictionary *)aDictionary
{
    [super init];

    dictionary = [aDictionary copy];

    return self;
}

- free
{
    [dictionary release];

    return [super free];
}

- encodeUsing:(id <NXEncoding>)portal
{
    unsigned count;
    NSEnumerator *enumerator = [dictionary keyEnumerator];
    NSString *key;

    /*
     *  First encode the count
     */
    count = [dictionary count];
    [portal encodeData:&count ofType:"i"];

    /*
     *  Then encode the objects one by one
     */
   while(key = [enumerator nextObject]) {
	[portal encodeObject:key];
	[portal encodeObject:[dictionary objectForKey:key]];
    }

    return self;
}

- decodeUsing:(id <NXDecoding>)portal
{
    NSMutableDictionary *newDictionary = nil;
    unsigned count, i;

    /*
     *  We encoded the count first, and here it is
     */
    [portal decodeData:&count ofType:"i"];

    newDictionary = [NSMutableDictionary dictionaryWithCapacity:count];

    /*
     *  Decode the objects one by one and add them to the array
     */
    for(i=0; i<count; i++) {
	id newKey, newObject;

	newKey = [portal decodeObject];
	newObject = [portal decodeObject];

	if(!newKey || !newObject) {
            /*
             *  This should never happen, or we're in trouble.
             */
	    [NSException raise:NSInternalInconsistencyException format:@"%s: %s: can't decode key or object",
	     isa->name, sel_getName(_cmd)];
	}
	else {
	    [newDictionary setObject:newObject forKey:newKey];
	}
    }

    /*
     *  We return our mutable dictionary instance here even though we might
     *  be the placeholder for a regular NSDictionary.  There is usually no
     *  harm in returning a mutable dictionary in place of an immutable one.
     *  If there is, you need to implement some smarts here to return an
     *  instance of the appropriate class.
     */
    return newDictionary;
}

@end

